package cn.st4rlight.util.response;

import static com.google.common.net.HttpHeaders.CACHE_CONTROL;
import static com.google.common.net.HttpHeaders.CONTENT_DISPOSITION;
import static com.google.common.net.HttpHeaders.CONTENT_LENGTH;
import static com.google.common.net.HttpHeaders.EXPIRES;
import static com.google.common.net.HttpHeaders.PRAGMA;
import static org.apache.commons.codec.CharEncoding.UTF_8;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

import org.apache.commons.lang3.StringUtils;

import cn.st4rlight.util.exception.ServiceException;
import cn.st4rlight.util.json.ObjectMapperUtil;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

/**
 * @author st4rlight <st4rlight@163.com>
 * Created on 2024-05-04
 */
@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ResponseUtil {

    @SneakyThrows
    public static void resetErrorHttpResp(HttpServletResponse response, String errMsg) {
        resetErrorHttpResp(response, ResultCode.BIZ_CHECK_INVALID, errMsg);
    }

    @SneakyThrows
    public static void resetErrorHttpResp(HttpServletResponse response, ResultCode resultCode) {
        resetErrorHttpResp(response, resultCode, "");
    }

    @SneakyThrows
    public static void resetErrorHttpResp(HttpServletResponse response, ResultCode resultCode, String errMsg) {
        errMsg = StringUtils.defaultIfEmpty(errMsg, resultCode.getMsg());
        Message<Void> resultMessage = Message.error(resultCode.getCode(), errMsg);

        response.reset();
        response.setContentType("application/json;charset=UTF-8");
        response.setCharacterEncoding(UTF_8);
        response.getWriter().println(ObjectMapperUtil.toJson(resultMessage));
    }

    /**
     * 写出数据到http响应流中
     * NOTE: 正常不推荐，最好还是有一个中间存储，然后返回uri或者url，或者约定一个下载接口
     *
     * @param fullFileName 完整输出文件名
     * @param excelBytes 数据的字节数组
     * @param response http响应
     */
    public static void writeExcelToResp(String fullFileName, byte[] excelBytes, HttpServletResponse response) {
        log.info("writeExcelToResp fileName: {}", fullFileName);
        response.setCharacterEncoding(UTF_8);
        response.setContentType("application/vnd.ms-excel;charset=UTF-8");
        response.setHeader(PRAGMA, "no-cache");
        response.setHeader(CACHE_CONTROL, "no-cache");
        response.setHeader(CONTENT_LENGTH, excelBytes.length + "");
        response.setDateHeader(EXPIRES, 0);

        try (ServletOutputStream outputStream = response.getOutputStream()) {
            response.setHeader(CONTENT_DISPOSITION,
                    "attachment;filename=" + URLEncoder.encode(fullFileName, StandardCharsets.UTF_8));
            outputStream.write(excelBytes);
        } catch (IOException ex) {
            log.error("写出数据到http响应流中失败", ex);
            throw ServiceException.of("写出数据到http响应流中失败", ex);
        }
    }
}
